package com.travelsky.airchina.boarding.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.stereotype.Service;

import com.travelsky.airchina.boarding.dao.ResourceDAO;
import com.travelsky.airchina.boarding.domain.Resource;
import com.travelsky.airchina.boarding.dto.ResourceView;

@Service("resourceService")
public class ResourceService{
	@Autowired
	private ResourceDAO resourceDAO;
	private SimpleJdbcTemplate simpleJdbcTemplate;
	//private SimpleJdbcCall procAddResource;
	
	private class JdbcResourceViewRowMapper implements ParameterizedRowMapper<ResourceView> {
		public ResourceView mapRow(ResultSet rs, int rownum) throws SQLException {
			ResourceView resourceView = new ResourceView();
			resourceView.setId(rs.getLong("resource_id"));
			resourceView.setParentResourceId(rs.getLong("parent_resource_id"));
			resourceView.setName(rs.getString("resource_name"));
			resourceView.setDepth(rs.getInt("depth"));
			return resourceView;
		}
	}

	/**
	@Autowired
	public void setDataSource(DataSource dataSource) {
		simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
		procAddResource = new SimpleJdbcCall(dataSource).withProcedureName("add_resource");
	}
	*/
	public List<Resource> findResources(Long roleId) {
		return resourceDAO.findResources(roleId);
	}

	public Resource getResource(Long id) {
		return resourceDAO.findById(id);
	}

	public void saveOrUpdateResource(Resource resource) {
		resourceDAO.makePersistent(resource);
	}

	public List<Resource> findAllResource(String type, String status) {
		return resourceDAO.findAllResource(type,status);
	}

	public List<Resource> findAllParentResourcesByChildId(Long id) {
		return resourceDAO.findAllParentResourcesByChildId(id);
	}
	public Map<Long, List<Resource>> findChildrenResourceByParentId(List<Long> resourceIds, Long id) {
		List<Resource> list = resourceDAO.findChildrenResourceByParentId(resourceIds);
		Map<Long,List<Resource>> map = new LinkedHashMap<Long,List<Resource>>();
		if(list!=null && list.size()>0){
			for(Resource temp:list){
				if(temp.getParentResource().getId()!=null && !temp.getId().equals(id)){
					if(!map.containsKey(temp.getParentResource().getId())){
						List<Resource> listTemp = new ArrayList<Resource>();
						listTemp.add(temp);
						map.put(temp.getParentResource().getId(), listTemp);
					}else{
						map.get(temp.getParentResource().getId()).add(temp);
					}
				}
			}
		}
		return map;
	}

	public List<Resource> findResourcesByParentId(Long parentId) {
		return resourceDAO.findResourcesByParentId(parentId);
	}

	public int getResourceSum() {
		return resourceDAO.getResourceSum();
	}

	public void saveResource(Resource resource) {
		/**
		int childCount = 0;
		if(resource.getParentResource()!=null && resource.getParentResource().getId()!=null){
			resourceDAO.updateResourceLeaf(resource.getParentResource().getId(),"0");
			Long parentResourceId = resource.getParentResource().getId();
			childCount = resourceDAO.getResourceChildCount(parentResourceId);
			Resource parentResource = resourceDAO.findById(parentResourceId);
			if(childCount>0){
				Resource lastNode = resourceDAO.getLastNodeOfParent(parentResourceId);
				int rightNumber = lastNode.getRightNumber();
				resourceDAO.updateRightNumber(rightNumber);
				resourceDAO.updateLeftNumber(rightNumber);
				resource.setLeftNumber(rightNumber+1);
				resource.setRightNumber(rightNumber+2);
			}else{
				int parentLeftNumber = parentResource.getLeftNumber();
				resourceDAO.updateRightNumber(parentLeftNumber);
				resourceDAO.updateLeftNumber(parentLeftNumber);
				resource.setLeftNumber(parentLeftNumber+1);
				resource.setRightNumber(parentLeftNumber+2);
			}
			resourceDAO.makePersistent(resource);
		}else{
			resource.setLeftNumber(1);
			resource.setRightNumber(2);
			resourceDAO.makePersistent(resource);
		}
		SqlParameterSource in = new MapSqlParameterSource()
		.addValue("parent_resource_id", parentResourceId)
		.addValue("resource_name", resource.getName())
		.addValue("resource_url", resource.getUrl())
		.addValue("resource_type", resource.getType())
		.addValue("resource_status", resource.getStatus())
		.addValue("is_leaf", resource.getIsLeaf())
		.addValue("is_parent_leaf", "0")
		.addValue("sort_order", resource.getSortOrder())
		.addValue("child_count", childCount); 
		Map out = procAddResource.execute(in);
		resource.setId((Long)out.get("resource_id_out"));
		resourceDAO.makePersistent(resource);
		if(resource.getParentResource()!=null && resource.getParentResource().getId()!=null){
			resourceDAO.updateResourceLeaf(resource.getParentResource().getId(),"0");
		}
		*/
		resourceDAO.makePersistent(resource);
		if(resource.getParentResource()!=null && resource.getParentResource().getId()!=null){
			resourceDAO.updateResourceLeaf(resource.getParentResource().getId(),"0");
		}
	}
	public void deleteResource(Long id){
		Resource resource = resourceDAO.findById(id);
		int leftNumber = resource.getLeftNumber();
		int rightNumber = resource.getRightNumber();
		int myWidth = rightNumber - leftNumber + 1;
		resourceDAO.deleteSubTreeNode(leftNumber,rightNumber);
		resourceDAO.updateRightNumberWhenDeleteLeafNode(rightNumber,myWidth);
		resourceDAO.updateLeftNumberWhenDeleteLeafNode(rightNumber,myWidth);
	}
	public void updateResource(Resource resource, Long oldParentResourceIdL) {
		saveResource(resource);
		if(oldParentResourceIdL!=null){
			if(resource.getParentResource()!=null && resource.getParentResource().getId()!=null){
				if(!resource.getParentResource().getId().equals(oldParentResourceIdL)){
					resourceDAO.updateResourceLeaf(oldParentResourceIdL);
				}
			}
		}
	}

	@SuppressWarnings("deprecation")
	public List<ResourceView> findResourceView(){
		String sql = "SELECT node.resource_id,node.parent_resource_id,node.resource_name,(COUNT(parent.resource_id)-1) as depth FROM boarding_resource as node,boarding_resource as parent WHERE node.left_number BETWEEN parent.left_number AND parent.right_number GROUP BY node.resource_id ORDER BY node.left_number";
		List<ResourceView> list = (List<ResourceView>)this.simpleJdbcTemplate.query(sql,new JdbcResourceViewRowMapper());
		return list;
	}
	
	
}
